The circumference of an ellipse
This notebook is inspired by Matt Parker's video on the same topic. Notebook by Luka van der Plas.
You are (hopefully) familiar with the formula to calculate the circumference of a circle. If we have a circle with radius
... then the circumference
But what is the formula for an ellipse?
Because an ellipse is elongated, we can't just describe it with a single value for the radius. Instead, we give the semi-major axis,
(The semi-bit means that we go form the centre to the edge, not from one edge to the other. So
Let's start by making a structure for that.
xxxxxxxxxx
xxxxxxxxxx
struct Ellipse
a
b
#constructors
Ellipse(a,b) = a >= b ? new(a,b) : error("a must be the larger axis")
Ellipse(a) = a >= 1 ? new(a, 1) : error("a must be the larger axis")
end
Our Ellipse
struct stores the valus of
You can also make an ellipse by just given a value for
Okay, let's make an ellipse!
xxxxxxxxxx
2
1
xxxxxxxxxx
shape = Ellipse(2)
You can retrieve the values of the axes by putting .a
or .b
behind the name.
xxxxxxxxxx
2
xxxxxxxxxx
shape.a
1
xxxxxxxxxx
These values are really all we need to do some geometry. But it's probably nice to have some visualisation as well. Here is a picture of our ellipse:
xxxxxxxxxx
xxxxxxxxxx
Beautiful.
Now, let's go back to our question: how do we calculate the circumference of an ellipse?
Surprisingly, there is no neat formula! There are some infinite series, but those are not exactly easy to use. For example, we can calculate the circumference
where
Oof.
Don't worry about understanding the formula. One thing of note: the formula contains an infinite sum (note the
This formula is a hassle to encode in a Julia in the 21st century. (Don't worry, I already did that for you.) But using a formula like that was even worse in History Times, when people did not have computers at their disposal. So instead, people would use approximation functions.
An approximation function will give you something close to the real circumference, but it's easier to calculate. That is what we will do in this notebook! We can encode some functions and compare them to the "true" value of the circumference.
xxxxxxxxxx
Approximations
Let's define some approximation functions. A function should take an ellipse as input, and return the circumference. Here is a simple example:
xxxxxxxxxx
Ï€_a_plus_b (generic function with 1 method)
xxxxxxxxxx
9.42477796076938
xxxxxxxxxx
To compare these functions, we will keep them in a Dict
. This one will store a good name for the function, and the function itself. The names will be useful when we make a plot.
xxxxxxxxxx
"Matt Parker"
parker
"Ï€(a + b)"
Ï€_a_plus_b
"Ramanujan"
ramanujan
xxxxxxxxxx
Some more functions. You can add more your own (see Matt's video for inspiration), or even try to find the best function you can!
(Remember that if you want to add a function to the plot below, you have to include it in the approximations
dict.)
xxxxxxxxxx
ramanujan (generic function with 1 method)
xxxxxxxxxx
parker (generic function with 1 method)
xxxxxxxxxx
Results
This plot shows how all of our functions are doing.
We are interested in the error of our function, i.e. how far it is from the real circumference. In this plot, we compare it to the ratio
xxxxxxxxxx
TypeError: non-boolean (Missing) used in boolean context
- top-level scope@Local: 2[inlined]
- top-level scope@none:0
xxxxxxxxxx
Here are some options for your plot:
xxxxxxxxxx
Turn all errors into postive values
xxxxxxxxxx
Divide the error by the circumference. Note that you will probably need to adjust the scale as well.
xxxxxxxxxx
Maximum error:
What should be the limit on the y axis?
xxxxxxxxxx
Maximum
What should be the limit on the x-axis?
xxxxxxxxxx
Number of data points:
Slide up if you want more precision in the plot, slide down if you want to speed up calculations.
xxxxxxxxxx
The true circumference
If you are interested, here is the code I used to calculate the "true" circumference and to compare that with the approximations.
Though you probably remember the formula, this is the infinite series we can use to get the true circumference.
where
As I mentioned, you can sum to a particular value of
xxxxxxxxxx
circumference (generic function with 1 method)
xxxxxxxxxx
double_factorial (generic function with 1 method)
xxxxxxxxxx
h (generic function with 1 method)
xxxxxxxxxx
9.688448220547656
xxxxxxxxxx
To create the plot, we generate a range of values for the
xxxxxxxxxx
TypeError: in keyword argument length, expected Union{Nothing, Integer}, got a value of type Missing
- top-level scope@Local: 1[inlined]
xxxxxxxxxx
true_curve (generic function with 1 method)
xxxxxxxxxx
UndefVarError: test_ratios not defined
- top-level scope@Local: 1
xxxxxxxxxx
For a particular approximation function, we can get the errors by applying the function to each ratio, and substracting the true circumference from the result.
xxxxxxxxxx
error_curve (generic function with 1 method)
xxxxxxxxxx
To get the relative error, we also divide by the circumference.
xxxxxxxxxx
relative_error_curve (generic function with 1 method)
xxxxxxxxxx
Lastly, here is the function I used to display the ellipse in the beginning.
xxxxxxxxxx
show_ellipse (generic function with 1 method)
xxxxxxxxxx
xxxxxxxxxx